function numberEnd(s1, offset) {
  // 现在只能解析普通数字
  // 小数 负数 都不能解析
  var digits = "1234567890";
  for (var i = 0; i < s1.length - offset; i++) {
    var c = s1[offset + i];
    if (!digits.includes(c)) {
      return i;
    }
  }
  console.log("** 错误, 数字解析错误");
}
function stringEnd(s1, offset) {
  const bs = {
    b: "\b",
    f: "\f",
    n: "\n",
    r: "\r",
    t: "\t",
    "/": "/",
    '"': '"',
    "\\": "\\",
  };

  let res = "";
  let i = offset;

  while (i < s1.length) {
    const a = s1[i];
    if (a === '"') {
      return [res, i];
    } else if (a === "\\") {
      const b = s1[i + 1];
      if (b in bs) {
        res += bs[b];
        i += 2;
      } else {
        console.log("** 错误, 不合法的转义字符: ", a + b);
        const example = '\\b \\f \\n \\r \\t \\/ \\" \\\\';
        console.log("合法的转义字符是: ", example);
        return ["", -1];
      }
    } else {
      res += a;
      i += 1;
    }
  }

  return [res, i];
}

// 示例
const exampleString = 'abc\\n123';
const [resultString, indexString] = stringEnd(exampleString, 3);
console.log(resultString, indexString);

const exampleNumber = '12345abc';
const resultNumber = numberEnd(exampleNumber, 0);
console.log(resultNumber);

function loads(code) {
  let i = 0;
  const length = code.length;
  const tokens = [];
  const spaces = " \b\f\n\r\t";
  const digits = "0123456789";

  let is_open = true;
  while (i < length) {
    const c = code[i];
    i++;

    if (spaces.includes(c)) {
      continue;
    } else if (":,[]{}".includes(c)) {
      const t = new Token(Type.auto, c);
      tokens.push(t);
    } else if (c === '"' && is_open) {
      // 吃字符串
      const resultAndIndex = stringEnd(code, i);
      const result = resultAndIndex.result;
      const index = resultAndIndex.index;

      if (index !== -1) {
        const t = new Token(Type.string);
        t.value = result;
        i = index;
        tokens.push(t);
        is_open = !is_open;
      } else {
        return;
      }
    } else if (c === '"' && !is_open) {
      is_open = !is_open;
      continue;
    } else if (digits.includes(c)) {
      // 吃数字
      const offset = numberEnd(code, i);
      const t = new Token(Type.number);
      t.value = parseInt(code.slice(i - 1, i + offset));
      i += offset;
      tokens.push(t);
    } else if ("tfn".includes(c)) {
      // true false null
      const kvs = {
        t: "true",
        f: "false",
        n: "null",
      };

      const t = new Token(Type.keyword);
      t.value = kvs[c];
      tokens.push(t);
      i += kvs[c].length;
    } else {
      console.log("*** 错误", c, code.slice(i, i + 10));
      return;
    }
  }

  return tokens;
}

function tokenList(code) {
  return loads(code);
}
